home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
presto
/
prest1_0.lha
/
src
/
spinlock_impl.h
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-11
|
4KB
|
167 lines
#ifndef __spinlock_impl_h__
#define __spinlock_impl_h__
// Spinlock inline implementations
// Must follow defs for threads, but precede everything else.
//
// Modification History:
//
// 28-Dec-1989 JEF
// Add class HC_Spinlock (for sequent symmetry only). This variation of
// a spinlock works well when there is high contention for the lock.
// After original by raj.
//
#if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
/*
* Optimized version of S_LOCK to only make the procedure call
* if the lock is held. Would really like to use S_LOCK here,
* but (potentially) inline functions can't handle loops.
*/
SPINLOCK_INLINE
void
Spinlock::lock()
{
#ifdef ns32000
char *lock_alm = &_alm_base[ALM_HASH(sl_lock)];
#endif
//
// Must mark ourselves in the lock even before we acquire it.
// Otherwise, we could hold the lock and be preempted. If we
// were holding the lock on something that the preemption code
// needed (or someone else, in order to ensure we run), we would
// deadlock. Must make lock acquisition and thread in spin cs
// marking atomic.
//
#ifndef NO_PREEMPT
thisthread->holdingspinlock();
#endif /* NO_PREEMPT */
#ifdef ns32000
if (sl_lock == L_LOCKED) // u lose
(void)s_lock(&sl_lock);
else if (*lock_alm & ALM_LOCKED) // u lose
(void)s_lock(&sl_lock);
else if (sl_lock == L_LOCKED) { // u lose (race condition)
*lock_alm = ALM_UNLOCKED;
(void)s_lock(&sl_lock);
} else { // u win
sl_lock = L_LOCKED;
*lock_alm = ALM_UNLOCKED;
}
#else
//
// No ALM's in Symmetry. We use S_LOCK() and to avoid
// another out-of-line call. Since C++ doesn't understand
// asm-functions, must use "CC +hasmdefs.h".
//
// On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
// Should probably be inline.
//
//cout << "regular old spinlock.lock\n"; cout.flush ();
#ifdef PROFILE
SLLock(sl_q);
#endif
(void) S_LOCK(&sl_lock);
#endif
}
SPINLOCK_INLINE
void
Spinlock::unlock()
{
//cout << "regular old spinlock.unlock\n"; cout.flush ();
(void) S_UNLOCK(&sl_lock);
#ifdef PROFILE
SLUnlock(sl_q);
#endif
#ifndef NO_PREEMPT
thisthread->releasingspinlock();
#endif /* NO_PREEMPT */
}
SPINLOCK_INLINE
Spinlock::~Spinlock()
{
//
// We should abort if the lock is not free. (?) XXX
// For now just unlock it for backward compatibility.
//
if (testlock())
unlock();
#ifdef PROFILE
SLDispose(sl_q);
#endif
}
#endif /* DO_SPINLOCK_INLINE || SPINLOCK_C */
//
// HC_Spinlock inline implementations.
//
#ifdef i386
SPINLOCK_INLINE
void
HC_Spinlock::lock()
{
//
// Must mark ourselves in the lock even before we acquire it.
// Otherwise, we could hold the lock and be preempted. If we
// were holding the lock on something that the preemption code
// needed (or someone else, in order to ensure we run), we would
// deadlock. Must make lock acquisition and thread in spin cs
// marking atomic.
//
#ifndef NO_PREEMPT
thisthread->holdingspinlock();
#endif /* NO_PREEMPT */
//
// HC_S_LOCK is an inline straight C asm function defined in
// hc_slock_asm.h, which is pulled into the C++ C output via
// the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
//
//cout << "high contention spinlock.lock\n"; cout.flush ();
#ifdef PROFILE
SLLock(sl_q);
#endif
(void) HC_S_LOCK(&sl_lock);
}
inline
void
HC_Spinlock::unlock()
{
//
// HC_S_UNLOCK is an inline straight C asm function defined in
// hc_slock_asm.h, which is pulled into the C++ C output via
// the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
//
//cout << "high contention spinlock.unlock\n"; cout.flush ();
(void) HC_S_UNLOCK(&sl_lock);
#ifdef PROFILE
SLUnlock(sl_q);
#endif
#ifndef NO_PREEMPT
thisthread->releasingspinlock();
#endif /* NO_PREEMPT */
}
#endif /* i386 */
#endif /* __spinlock_impl_h__ */